package org.jeecgframework.web.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jeecgframework.core.common.controller.BaseController;
import org.jeecgframework.core.common.model.json.AjaxJson;
import org.jeecgframework.core.common.model.json.DataGrid;
import org.jeecgframework.core.util.FileUtils;
import org.jeecgframework.core.util.StringUtil;
import org.jeecgframework.web.service.UploadEquipmentService;
import org.jeecgframework.web.system.pojo.base.ZyUpEquipmentCheckSnThread;
import org.jeecgframework.web.system.service.SystemService;
import org.jeecgframework.web.util.FileBean;
import org.jeecgframework.web.util.StaticValue;
import org.jeecgframework.web.util.UploadFileUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

/**
 * @Title: UploadEquipmentController
 * @Description: 上传设备信息
 * @author ZhangYunlong
 * @date 2016-04-01
 * @version V1.0
 * 
 */
@Scope("prototype")
@Controller
@RequestMapping("/uploadEquipmentController")
public class UploadEquipmentController extends BaseController {

	@Autowired
	private UploadEquipmentService uploadEquipmentService;
	@Autowired
	private SystemService systemService;

	/**
	 * 设备以及备件信息列表 页面跳转
	 * 
	 * @return
	 */
	@RequestMapping(params = "uploadFile")
	public ModelAndView uploadFile(HttpServletRequest request) {
		return new ModelAndView("com/zybk/file_upload/uploadEquipmentSpare");
	}

	@ResponseBody
	@RequestMapping(params = "importExcel")
	public AjaxJson importExcel(HttpServletRequest request, HttpServletResponse response) throws IOException {
		AjaxJson aj = new AjaxJson();
		try {
			FileBean fileBean = UploadFileUtil.UploadFile(request);
			if (fileBean == null) {
				// 文件为空
				aj.setSuccess(false);
				aj.setMsg("上传文件错误，请修改后在导入！");
				return aj;
			}
			return systemService.doSaveZyFileLog(fileBean, StaticValue.IMPORT_FILE_EQUIPMENT_SPARE_BASE_DATA, "", StaticValue.DIC_FILE_TYPE_XLSX, StaticValue.DIC_TRUE_OR_FALSE_NUM_0);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return aj;
	}

	/**
	 * @Title：uploadFileByRenewal
	 * @Description：中影续保导入
	 * @author：LeiYoung
	 * @Date：2016年10月12日 下午1:17:47
	 * @param request
	 * @return ModelAndView
	 */
	@RequestMapping(params = "uploadFileByRenewal")
	public ModelAndView uploadFileByRenewal(HttpServletRequest request) {
		return new ModelAndView("com/zybk/file_upload/uploadEquipmentSpareByRenewal");
	}

	/**
	 * @author xiul
	 * 2016-11-28 下午7:54:25
	 * Description 中影续保导入 
	 */
	@ResponseBody
	@RequestMapping(params = "importExcelByRenewal")
	public AjaxJson importExcelByRenewal(HttpServletRequest request, HttpServletResponse response) throws IOException {
		AjaxJson aj = new AjaxJson();
		FileBean fileBean = UploadFileUtil.UploadFile(request);
		try {
			uploadEquipmentService.doCheckAndUpdateExcelByRenewal(fileBean, aj);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return aj;

	}
	
	/**
	 * 导出excel 模板
	 * 
	 * @param request
	 * @param response
	 */
	@RequestMapping(params = "exportXlsByT")
	public void exportXlsByT(HttpServletRequest request, HttpServletResponse response, DataGrid dataGrid, ModelMap modelMap) {
		try {
			@SuppressWarnings("deprecation")
			String templatePath = request.getRealPath("/") + "temp/FilmRenewalTemplate.xlsx";
			FileUtils.downFile(templatePath, "中影续保.xlsx", response);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@ResponseBody
	@RequestMapping(params = "doHandlerExcel")
	public AjaxJson doHandlerExcel(HttpServletRequest request) {
		System.out.println("进入 导入设备 比对SNAction");
		AjaxJson j = new AjaxJson();
		boolean flag = true;
		String msg = "导入成功";
		long begin = System.currentTimeMillis();
		List<Map<String, String>> snMapList = uploadEquipmentService.parseExcel(request, j);
		try {
			Map<String, String> repeatSnMap = null;
			int maxUnit = 2000;
			int countRow = snMapList.size();
			if (countRow > maxUnit) {
				int threadC = countRow % maxUnit > 0 ? countRow / maxUnit + 1 : countRow / maxUnit;
				System.out.println("threadC:" + threadC);
				System.out.println("snList:" + snMapList.size());
				ThreadPoolExecutor exec = (ThreadPoolExecutor) Executors.newFixedThreadPool(threadC);
				ArrayList<Future<Map<String, String>>> results = new ArrayList<Future<Map<String, String>>>();
				for (int i = 0; i < threadC; i++) {
					int beginR = i == 0 ? 1 : i * maxUnit + 1;
					int endR = i == (threadC - 1) ? countRow : beginR + maxUnit - 1;
					results.add(exec.submit(new ZyUpEquipmentCheckSnThread(snMapList, beginR, endR)));
				}
				do {
					for (Future<Map<String, String>> fs : results) {
						if (fs.isDone()) {
							if (StringUtil.isNotEmpty(fs.get())) {
								msg = "item:" + fs.get().get("item").trim() + "中的 SN：" + fs.get().get("sn").trim() + "，重复";
								System.err.println(msg);
								flag = false;
								break;
							}
						}
					}
				} while (exec.getCompletedTaskCount() < results.size() && flag);
				exec.shutdown();
			} else {
				repeatSnMap = uploadEquipmentService.checkSnRepeat(snMapList, 0, snMapList.size() - 1);
				if (StringUtil.isNotEmpty(repeatSnMap)) {
					msg = "item:" + repeatSnMap.get("item").trim() + "中的 SN：" + repeatSnMap.get("sn").trim() + "，重复";
					flag = false;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		long end = System.currentTimeMillis();
		System.out.println("设备Excel 解析并比对 sn 完毕，用时：" + (end - begin) / 1000 + "." + (end - begin) % 1000 + "秒");
		j.setMsg(msg);
		j.setSuccess(flag);
		return j;
	}

	@ResponseBody
	@RequestMapping(params = "checkExcel")
	public AjaxJson checkExcel(HttpServletRequest request) {
		System.out.println("进入 导入设备 比对SNAction");
		AjaxJson j = new AjaxJson();
		boolean flag = true;
		String msg = "导入成功";
		long begin = System.currentTimeMillis();
		List<Map<String, String>> snMapList = uploadEquipmentService.parseExcel(request, j);
		try {
			Map<String, String> repeatSnMap = null;
			int maxUnit = 2000;
			int countRow = snMapList.size();
			if (countRow > maxUnit) {
				int threadC = countRow % maxUnit > 0 ? countRow / maxUnit + 1 : countRow / maxUnit;
				System.out.println("threadC:" + threadC);
				System.out.println("snList:" + snMapList.size());
				ThreadPoolExecutor exec = (ThreadPoolExecutor) Executors.newFixedThreadPool(threadC);
				ArrayList<Future<Map<String, String>>> results = new ArrayList<Future<Map<String, String>>>();
				for (int i = 0; i < threadC; i++) {
					int beginR = i == 0 ? 1 : i * maxUnit + 1;
					int endR = i == (threadC - 1) ? countRow : beginR + maxUnit - 1;
					results.add(exec.submit(new ZyUpEquipmentCheckSnThread(snMapList, beginR, endR)));
				}
				do {
					for (Future<Map<String, String>> fs : results) {
						if (fs.isDone()) {
							if (StringUtil.isNotEmpty(fs.get())) {
								msg = "item:" + fs.get().get("item").trim() + "中的 SN：" + fs.get().get("sn").trim() + "，重复";
								System.err.println(msg);
								flag = false;
								break;
							}
						}
					}
				} while (exec.getCompletedTaskCount() < results.size() && flag);
				exec.shutdown();
			} else {
				repeatSnMap = uploadEquipmentService.checkSnRepeat(snMapList, 0, snMapList.size() - 1);
				if (StringUtil.isNotEmpty(repeatSnMap)) {
					msg = "item:" + repeatSnMap.get("item").trim() + "中的 SN：" + repeatSnMap.get("sn").trim() + "，重复";
					flag = false;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		long end = System.currentTimeMillis();
		System.out.println("设备Excel 解析并比对 sn 完毕，用时：" + (end - begin) / 1000 + "." + (end - begin) % 1000 + "秒");
		j.setMsg(msg);
		j.setSuccess(flag);
		return j;
	}

	/**
	 * @author xiul 2016-6-17 上午11:12:39 Description 对比完SN之后 保存数据
	 * @param filePath
	 *            上传的excel保存路径
	 */
	@ResponseBody
	@RequestMapping(params = "readExcel")
	public void readExcel(HttpServletRequest request, @RequestParam(value = "filePath") String filePath) {
		System.out.println(">>>>>>>>>>>>>>>>>>>>>>>进入解析EXCEL action");
		long begin = System.currentTimeMillis();
		ThreadLocal<HttpServletRequest> req = new ThreadLocal<HttpServletRequest>();
		req.set(request);
		uploadEquipmentService.readExcel(filePath);
		long end = System.currentTimeMillis();
		System.out.println("解析EXCEL数据并启动线程保存  用时：" + (end - begin) / 1000 + "." + (end - begin) % 1000 + "秒");
	}

}
